import { defineStore } from "pinia";
import cloneDeep from 'lodash.clonedeep'
import type { RouteRecordRaw } from 'vue-router'
import staticRouters from "@/router/static-routers";
import dynamicRoutes from "@/router/dynamic-routes";
import { shallowRef } from "vue";
import type { MenuData, MenuDataItem  } from "@/types/typing";
import type { Permissions, Role } from '@/api/user/types'

/**
 * 过滤账户是否拥有某一个权限，并将菜单从加载列表移除
 *
 * @param permission
 * @param route
 * @returns {boolean}
 */
function hasPermission (permission: Permissions[] | undefined, route: RouteRecordRaw): boolean {
  if (route.meta && route.meta.permission) {
    if (permission === undefined) {
      return false
    }
    let flag = false
    for (let i = 0, len = permission.length; i < len; i++) {
      flag = route.meta?.permission.includes(permission[i].permissionCode)
      if (flag) {
        return true
      }
    }
    return false
  }
  return true
}

/**
 * 单账户多角色时，使用该方法可过滤角色不存在的菜单
 *
 * @param roles
 * @param route
 * @returns {*}
 */
function hasRole(roles: Role | undefined, route: RouteRecordRaw): boolean {
  if (route.meta && route.meta.roles) {
    return route.meta.roles.includes(roles?.roleCode as string)
  } else {
    return true
  }
}

function filterAsyncRouter (routerMap: RouteRecordRaw[], role: Role | undefined): RouteRecordRaw[] {
  const accessedRouters = routerMap.filter(route => {
    if (hasPermission(role?.permissions, route)) {
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children, role)
      }
      return true
    }
    return false
  })
  return accessedRouters
}

let cache_key = 1

const getCacheKey = () => `Cache_Key_${cache_key++}`


export const usePermissionStore = defineStore('permission', () => {
  const menuData = shallowRef<MenuData>([])

  const routers = shallowRef();
  const addRouters = shallowRef<RouteRecordRaw[]>([]);

  function formatMenu(route: RouteRecordRaw, path?: string) {
    return <MenuDataItem>{
      id: route.meta?.id,
      parentId: route.meta?.parentId,
      title: route.meta?.title,
      icon: route.meta?.icon || '',
      path: path ?? route.path,
      hideInMenu: route.meta?.hideInMenu || false,
      parentKeys: route.meta?.parentKeys || [],
      hideInBreadcrumb: route.meta?.hideInBreadcrumb || false,
      hideChildrenInMenu: route.meta?.hideChildrenInMenu || false,
      locale: route.meta?.locale,
      keepAlive: route.meta?.keepAlive || false,
      name: route.name as string,
      url: route.meta?.url || '',
      target: route.meta?.target || '_blank',
      disabled: route.meta?.disabled || false,
      permission: route.meta?.permission || [],
    }
  }

  // 本地静态路由生成菜单的信息
  const genRoutes = (routes: RouteRecordRaw[]| undefined, parent?: MenuDataItem): MenuData => {
    const menuData: MenuData = []
    if (routes) {
      for (const route of routes) {
        let path = route.path
        if (!path.startsWith('/')) {
          // 判断当前是不是以 /开头，如果不是就表示当前的路由地址为不完全的地址
          path = parent ? `${parent.path}/${path}` : `/${path}`;
        }
        // 判断是不是存在name，如果不存在name的情况下，自动补充一个自定义的name，为了更容易的去实现保活的功能，name是必须的
        if (!route.name) route.name = getCacheKey()
        const item: MenuDataItem = formatMenu(route, path)

        if (route.children && route.children.length)
          item.children = genRoutes(route.children, item)
        if (item.children?.length === 0)
          delete item.children
        menuData.push(item)
      }
    }
    return menuData
  }

  const generateRoutes = async (roles: Role | undefined) => { // 生成路由表，用于显示菜单和路由
    const cloneRouter = cloneDeep(dynamicRoutes); // 深拷贝路由表，用于显示菜单和路由
    const accessedRouters = filterAsyncRouter(cloneRouter, roles); // 过滤路由表，用于显示菜单和路由
    addRouters.value = accessedRouters; // 设置动态路由表，用于显示菜单和路由
    routers.value = staticRouters.concat(addRouters.value);
    menuData.value = genRoutes(accessedRouters);
    return addRouters.value; // 返回路由表，用于显示菜单和路由
  };

  return {
    menuData,
    routers,
    generateRoutes,
  }

})
